﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

// std headers
#include <memory>

// qt headers
#include <QObject>

// gcmp headers

#include "GcsService.h"


namespace gmepgcs
{
    class GCS_SERVICE_EXPORTS WorkflowBase : public QObject
    {
        Q_OBJECT

    public:
        explicit WorkflowBase(QObject *parent = nullptr);
        virtual ~WorkflowBase();

    public:
        template<typename Func>
        WorkflowBase *OnFinish(Func handler);

        template<typename Func>
        WorkflowBase *OnSuccess(Func handler);

        template<typename Func>
        WorkflowBase *OnFail(Func handler);

        template<typename Func>
        WorkflowBase *OnReport(Func handler);

        template<typename Func>
        WorkflowBase *OnProgress(Func handler);

        void Proceed(const bool deleteFinally = true);

    signals:
        void Finished(const bool success, const std::wstring message = std::wstring());
        void Report(const std::wstring message);
        void Progress(const float current, const float total);

    protected:
        virtual void InternalProceed() = 0;
    };


    template<typename Func>
    inline WorkflowBase * WorkflowBase::OnFinish(Func handler)
    {
        connect(this, &WorkflowBase::Finished, [=](const bool success, const std::wstring message) {
            handler(success, message);
        });

        return this;
    }

    template<typename Func>
    inline WorkflowBase * WorkflowBase::OnSuccess(Func handler)
    {
        connect(this, &WorkflowBase::Finished, [=](const bool success, const std::wstring message) {
            if (success)
            {
                handler(message);
            }
        });

        return this;
    }

    template<typename Func>
    inline WorkflowBase * WorkflowBase::OnFail(Func handler)
    {
        connect(this, &WorkflowBase::Finished, [=](const bool success, const std::wstring message) {
            if (!success)
            {
                handler(message);
            }
        });

        return this;
    }

    template<typename Func>
    inline WorkflowBase * WorkflowBase::OnReport(Func handler)
    {
        connect(this, &WorkflowBase::Report, [=](const std::wstring message) {
            handler(message);
        });

        return this;
    }

    template<typename Func>
    inline WorkflowBase * WorkflowBase::OnProgress(Func handler)
    {
        connect(this, &WorkflowBase::Progress, [=](const float current, const float total) {
            handler(current, total);
        });

        return this;
    }

}